package bubbleindex;

import java.util.concurrent.Callable;

/**
 *
 * @author ttrott
 */
public class MyCPUCallable implements Callable<Float> {
     
    private final int NumberOfDays;
    private final int j;
    
    public MyCPUCallable (int index, final int number) {
        NumberOfDays = number;
        j = index;
    }
    
    /**
     * This is a callable task to calculate the HQ derivative value of a 
     * given time series.
     * @return The HQ Derivative value, or The Value of the Bubble Index 
     */
    @Override
    public Float call() {

        if (!BuildIndex.Stop) {
            double[] TimeValues = new double[NumberOfDays];
            double[] TimeValues_M_Power = new double[NumberOfDays];
            double[] LogCosTimeValues = new double[NumberOfDays];
            double[] SelectedData = new double[NumberOfDays];
            double[] Coef = new double[3];

            for (int k = 0; k < NumberOfDays; k++) {
                TimeValues[k] = NumberOfDays + BubbleIndex.T_crit - k;
                TimeValues_M_Power[k] = Math.pow(TimeValues[k], 
                        BubbleIndex.M);
                LogCosTimeValues[k] = Math.cos(BubbleIndex.Omega * 
                    Math.log(TimeValues[k])) * TimeValues_M_Power[k];
                    SelectedData[k] = BubbleIndex.DailyPriceValues[k + j + 1];        
            }

            //Normalize data to a price starting at 100
            BuildIndex.Normalize(SelectedData, NumberOfDays);

            BuildIndex.DataReverse(SelectedData, NumberOfDays);

            BuildIndex.LinearFit(SelectedData, TimeValues_M_Power, LogCosTimeValues,
                        Coef, NumberOfDays);

            final float Temp = LombScargle.HQ_Derivative(TimeValues, 
                    Coef, NumberOfDays);
            final float output = Temp;
            
            final int DisplayPeriod = j + NumberOfDays;
            final int extra = NumberOfDays;
            final String DisplayPeriodString = BubbleIndex.DailyPriceDateList.get(DisplayPeriod);
            BubbleIndex.displayOutput("Name: " + BubbleIndex.SelectionName + " Date: " + DisplayPeriodString +
                            " Value: " + output + " Length: " + extra, false);
            
            return Temp;
        }
                
        else {            
            return 0.0f;      
        }
    }          
}